-- alu_tb.vhd
-- ALU test bench
-- Oleg Gavrilchenko
-- reffum@bk.ru

library ieee;
library my_arm;

use ieee.std_logic_1164.all;
use my_arm.common.all;
use my_arm.components.all;
use std.env.all;

entity alu_tb is 
end;

architecture imp of alu_tb is
   signal a, b, alu_out    :  std_logic_vector(C_BUS_WIDTH - 1 downto 0);
   signal carry            :  std_logic;
   signal func             :  alu_functions;
   signal flags            :  status_flags;
   
   type test_vector is record
      a, b, alu_out    :  std_logic_vector(C_BUS_WIDTH - 1 downto 0);
      carry            :  std_logic;
      func             :  alu_functions;
      flags            :  status_flags;
   end record;
   
   type test_vectors_array is array( natural range <> ) of test_vector;
   
   -- Test vectors
   constant test_vectors : test_vectors_array := ( 
	(x"FFFFFFFF", x"FFFFFFFF", x"00000000",'1', alu_0,    ('0', '0', '0', '0')),

	-- AND 
	(x"FFFFFFFF", x"FFFFFFFF", x"FFFFFFFF",'0', alu_and,  ('0', '0', '0', '0')),
	(x"FFFFFFFF", x"00000000", x"00000000", '0', alu_and, ('0', '0', '0', '0'))
   ); 
   
begin
   UUT: alu port map (
      i_a => a, i_b => b, i_carry => carry, i_function => func, 
      o_out => alu_out, o_flags => flags);
   
   -- Assign UUT inputs to each test vector 
   -- and check, that output match
   TEST:process
      alias tv is test_vectors;
   begin
      for i in test_vectors'range loop
         a <= tv(i).a;
         b <= tv(i).b;
         carry <= tv(i).carry;
         func <= tv(i).func;
         
         wait for 0 ns;
         
         assert alu_out = tv(i).alu_out   
            report "ALU simulation: alu_out error."   
            severity Failure;
            
         assert flags = tv(i).flags       
            report "ALU simulation: flags error."     
            severity Failure;
         
      end loop;
      report "ALU simulation: OK";
      
      finish(0);
      
      wait; -- Suppress warning
   end process;
   
end;
